﻿package core;


// ============================================================== Генератор
// тиков
public class Tick extends Thread {

//=================================================================== Переменные

private boolean fRun = true; // Флаг времени работы среды
private boolean fPause = true; // Флаг паузы
private boolean fUpdated; // Флаг обновления времени ожидания
private TickEvent event; // Обработчик события
private int delay; // Пауза между тиками, мс
private int id; // Идентификатор среды
private long nextTick; // Время следующего вызова
private String threadName; // Название текущего потока


//================================================================ Инициализация
public Tick(TickEvent event, int id, int delay, String threadName) {

	//	Mess.m("Tick.init", "===== id=" + id + ", delay=" + delay);
	this.id = id;
	this.event = event;
	this.delay = delay;
	this.threadName = threadName;
	this.update();
	this.start();
	resumeTick();
}


//======================================================================== Пауза
public void pauseTick() {

	Mess.m("Tick.pause", id + " Пауза");
	fPause = true;
}


/**/


//================================================================== Продолжение
public void resumeTick() {

	//	Mess.m("Tick.resume", id + " Продолжение");
	synchronized (this) {
		fPause = false;
		this.notifyAll();
	}
}


/**/


//============================================================ Остановка и выход
public void exit() {

	//Mess.m("Tick.stop", who + " Останов");
	fRun = false;
	fPause = false;
	this.interrupt();
	event = null;
}


//====================================================== Обновить время ожидания
public void update() {

	nextTick = System.currentTimeMillis() + delay;
	fUpdated = true;
}


//=============================================================== Среда анимации
public void run() {

	Thread.currentThread().setName(threadName);
	threadName = null;

	long sleepTime;
	long curTime = 0;

	//Mess.m("Tick.run", who + " Запуск");
	try {

		// Начальная пауза
		synchronized (this) {
			while (fPause) {
				this.wait();
			}
		}

		// Основной цикл
		while (fRun) {

			do {
				fUpdated = false;
				curTime = System.currentTimeMillis();
				sleepTime = nextTick - curTime;
				if (sleepTime > 0) {
					nextTick += delay;
					sleep(sleepTime);
				} else {
					nextTick = curTime + delay;
				}
			} while (fUpdated);

			if (fPause) {
				synchronized (this) {
					while (fPause) {
						this.wait();
					}
				}
			}

			event.tick(id);
			//Mess.m("Tick.run", "tick " + this.id);
		}
	} catch (InterruptedException e) {
		//Mess.m("Tick.run", "Завершаем работу ", e);
	} catch (Exception e) {
		Mess.err("Tick.run", id + " Исключение: ", e);
	}

	//	Mess.m("Tick.run", id + "Среда завершена");

}
}
